local jass = require 'jass.common'
local japi = require 'jass.japi'
local slk = require 'jass.slk'

local widget = {}
setmetatable(widget, widget)
ac.widget = widget

local mt = {}
widget.__index = mt 

-- 基类 单位 可破坏物 物品 都继承widget类
mt.type = 'widget'

--- 句柄
mt.handle = jass.ConvertUnitState(0)

-- [获取widget类型]
function mt:get_type()
    return self.type
end 

-- [获取widget生命]
function mt:get_life()
    return jass.GetWidgetLife(self.handle)
end 

-- [设置widget生命]
function mt:set_life(value)
    return jass.SetWidgetLife(self.handle, value)
end 

-- [获取widget位置]
function mt:get_point()
    return ac.point( jass.GetWidgetX(self.handle), jass.GetWidgetY(self.handle))
end 

-- [获取widgetx]
function mt:getx()
    return jass.GetWidgetX(self.handle)
end 

-- [获取widgety]
function mt:gety()
    return jass.GetWidgetY(self.handle)
end 

--设置自定义值
function mt:set_data(key, value)
    if not self.user_data then
        self.user_data = {}
    end
    self.user_data[key] = value
end

--获取自定义值
function mt:get_data(key)
    if not self.user_data then
        self.user_data = {}
    end
    return self.user_data[key]
end 

--[绑定特效]
function mt:add_effect(model, socket, time)
    return ac.effect.create{
        target = self,
        socket = socket,
        model = model,
        time = time,
    }
end 

--[绑定特效2]
function mt:add_attach(model, socket)
    local eff = ac.effect.create{
        model = model,
        target = ac.point(9999,9999,9999)
    }
    eff:bind(self, socket)
    return eff 
end 

--[造成伤害] 伤害对象
function mt:damage(damagetype)
    return function(dmgobject)
        local source = dmgobject.source
        local damage = dmgobject.damage 
        if not source or not damage or source.type ~= 'unit' then 
            return 
        end 
        jass.UnitDamageTarget(source.handle, self.handle, damage, false, false, 1,4, 0)
    end
end 

--[获取高度]
function mt:get_height()
    return 0
end 

--[获取缩放]
function mt:get_scale()
    return 1.0
end

--获取弹道命中z偏移
function mt:get_impactZ()
    return self:get_slk('impactZ', 64.0) * self:get_scale() 
end 

--获取弹道命中点
function mt:get_impact_point()
    local point = self:get_point()
    point.z = point:get_height() + self:get_height() + self:get_impactZ() 
    return point
end 

--[获取碰撞]
function mt:get_collision()
    return 32.0
end 

--获取的选取半径
function mt:get_selected_radius()
    return self:get_collision() + 32
end

--是否在指定位置附近(计算碰撞)
function mt:in_range(p, radius)
	return self:get_point() * p:get_point() - self:get_selected_radius() <= radius
end

--[设置模型]
function mt:set_model(model)
    self.model = model or ".mdx"
    japi.DzSetUnitModel(self.handle, model)
end 

--设置鼠标指向UI显示开关
function mt:set_press_ui_visible(flag)
    japi.SetUnitPressUIVisible(self.handle, flag or false)
end

--获取slk数据,第二项为默认值
function mt:get_slk(name, default, level)
    local typename = self.type
    if not typename then 
        return default
    end 
	local objecttype = slk[typename]
    if not objecttype then 
        log.error('物体类型错误', self, typename)
        return default
    end 
	local objectid = FourCC(self._id)
	if not objectid then 
		log.error('未获取到物体', self, self._id)
		return default
	end
    local objectdata = objecttype[objectid]
	if not objectdata then
		log.error('物体数据未找到',self, objectid, name)
		return default
	end
	local result = objectdata[name]
	if result == nil then
		return default
	end
    if level then 
        result = string.split(result, ',')[level]
    end
	if type(default) == 'number' then
		return tonumber(result) or default
	end
	return result
end

--获取单位模型
function mt:get_model()
    if not self.model then 
        local model = self:get_slk ('file','.mdx')
        local ftype = model:sub(-4):upper()
        if ftype ~= '.MDX' and ftype ~= '.MDL' then
            model = model .. '.mdx'
        end
        self.model = model 
    end 
    return self.model
end

--[删除所有特效]
function mt:search_effects()
    if not self.effects then 
        return function()
        end 
    end 
    local tbl = {}
    for _, effect in pairs(self.effects) do 
        table.insert(tbl, effect)
    end 
    table.sort(tbl, function(a, b)
        return a._index < b._index
    end)
    local n = 0
	return function (t, v)
		n = n + 1
		return t[n]
	end, tbl
end 

--[删除所有特效]
function mt:remove_effects()
    for eff in self:search_effects() do 
        eff:remove()
    end 
end 

function mt:remove_movers()
end 
function mt:remove_buffs()
end 
function mt:remove_sells()
end 
function mt:remove_skills()
end 
function mt:remove_attackers()
end 

return widget